package main

/*
#include <stdio.h>
#include <stdlib.h>
*/
import "C"

import (
	"fmt"
	"github.com/howeyc/fsnotify"
	"os"
	"path/filepath"
	"reflect"
	"unsafe"
	// "time"
	// "bufio"
)

func watch(p string) {
	path := p
	files := make([]string, 0)
	filepath.Walk(path, func(filename string, fi os.FileInfo, err error) error { //遍历目录
		if fi.IsDir() { // 忽略目录
			files = append(files, filename)
		}
		return err
	})
	watcher, err := fsnotify.NewWatcher()
	if err != nil {
		fmt.Println(err)
	}

	go func() {
		for {
			select {
			case name := <-watcher.Event:
				fmt.Println("Chanage:", name)
				// os.Exit(0)
			case err := <-watcher.Error:
				fmt.Println(err)
			}
		}
	}()
	// watcher.Watch(p)
	for _, i := range files {
		watcher.Watch(i)
	}
}

type YourT1 struct {
}

func (y *YourT1) MethodBar() {
	fmt.Println("MethodBar called")
}

type YourT2 struct {
}

func (y *YourT2) MethodFoo(i int, oo string) {
	fmt.Println("MethodFoo called", i, oo)
}

func InvokeObjectMethod(object interface{}, methodName string, args ...interface{}) {
	inputs := make([]reflect.Value, len(args))
	for i, _ := range args {
		inputs[i] = reflect.ValueOf(args[i])
	}
	reflect.ValueOf(object).MethodByName(methodName).Call(inputs)
}

func get(tonydon interface{}) {
	object := reflect.ValueOf(tonydon)
	myref := object.Elem()
	fmt.Println(myref)
	k := reflect.New(object.Type())
	fmt.Println(k)
	fmt.Println(myref.Addr())
	typeOfType := myref.Type()
	fmt.Println(typeOfType)
	fmt.Println(myref.NumMethod())
	for i := 0; i < myref.NumField(); i++ {
		field := myref.Field(i)
		fmt.Printf("%d. %s %s = %v \n", i, typeOfType.Field(i).Name, field.Type(), field.Interface())
	}
}

func test() {
	fmt.Println("...")
}

func main() {
	var t interface{}
	t = test
	t.(func())()
	a := &YourT2{}
	get(a)
	InvokeObjectMethod(new(YourT2), "MethodFoo", 10, "abc")
	InvokeObjectMethod(new(YourT1), "MethodBar")

	cstr := C.CString("Hello, world")
	C.puts(cstr)
	C.free(unsafe.Pointer(cstr))

	// watcher, err := fsnotify.NewWatcher()
	// if err != nil {
	// 	fmt.Println(err)
	// }

	// go func() {
	// 	for {
	// 		select {
	// 		case ev := <-watcher.Event:
	// 			fmt.Println("event:", ev)
	// 		case err := <-watcher.Error:
	// 			fmt.Println("error:", err)
	// 		}
	// 	}
	// }()
	// fmt.Println("...")
	// err = watcher.Watch("/root/xt/go/martini-go")
	// if err != nil {
	// 	fmt.Println(err)
	// }
	// time.Sleep(3000000000)
	watch("/home/negocat/.navicat/")
	// watch("/home/negocat/.wine/")

	ci := make(chan bool)
	<-ci
}
